package com.map.tool;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

public class MapProcessor 
{
    private BufferedImage map;// 图形对象
    private int viewportWidth;// 图形显示区的宽度
    private int viewportHeight;// 图形显示区的高度
    private int showCenterX;// 图形视觉中心的水平坐标
    private int showCenterY;// 图形视觉中心的垂直坐标
    private int cutMapWidth;// 截取图形的宽度
    private int cutMapHeight;// 截取图形的高度
    private float scale;// 缩放比例
    public MapProcessor(String mapPath, int viewportWidth, int viewportHeight, int scale) 
    {
        this.viewportWidth = viewportWidth;
        this.viewportHeight = viewportHeight;
        replaceMap(mapPath);
        dealWithScale(scale);
        dealWithCutMapSize();
    }

    public void replaceMap(String mapPath) 
    {
        try
        {
            map = ImageIO.read(new File(mapPath));
            this.showCenterX = map.getWidth() / 2;
            this.showCenterY = map.getHeight() / 2;
        } 
        catch (OutOfMemoryError ome)
        {
        	ome.printStackTrace();
        } 
        catch (IOException e)
        {
            e.printStackTrace();
        }
       
    }

  
    private ImageIcon cut()
    {
    	System.out.println("x,y:"+(showCenterX - cutMapWidth / 2)+","+(showCenterY - cutMapHeight / 2));
        System.out.println("width,height:"+cutMapWidth+","+cutMapHeight);
        System.out.println(">>>>>>x+width:"+(showCenterX - cutMapWidth / 2+cutMapWidth)+";map width:"+map.getWidth());
       
        BufferedImage subimage = map.getSubimage(
                showCenterX - cutMapWidth / 2, showCenterY - cutMapHeight / 2,// 开始截取点的坐标
                cutMapWidth, cutMapHeight);// 截取图形的大小
        
        return new ImageIcon(subimage.getScaledInstance(viewportWidth, viewportHeight, BufferedImage.SCALE_DEFAULT));// 返回当前显示的图形
        
    }

    public ImageIcon adjustWindow(int viewportWidth, int viewportHeight)
    {
        this.viewportWidth = viewportWidth;// 设置视口宽度
        this.viewportHeight = viewportHeight;// 设置视口高度
        dealWithCutMapSize();// 处理需要截取图形的大小
        validateShowCenterX();// 验证图形视觉中心的水平坐标
        validateShowCenterY();// 验证图形视觉中心的垂直坐标
        return this.cut();// 返回当前显示的图形
    }
    
    public ImageIcon adjustScale(int scale) 
    {
        float forestallScale = this.scale;// 调整前的比例
        dealWithScale(scale);// 处理比例
        dealWithCutMapSize();// 处理需要截取图形的大小
        if (this.scale < forestallScale)
        {
        	// 比例缩小，图形的视觉中心可能变化
            validateShowCenterX();// 验证图形视觉中心的水平坐标
            validateShowCenterY();// 验证图形视觉中心的垂直坐标
        }
        return this.cut();// 返回当前显示的图形

    }
    //水平移动
    public ImageIcon moveOfHorizontal(int distance)
    {
    	 return movePic(distance,0);// 返回当前显示的图形
    }
    
     //垂直移动
    public ImageIcon moveOfVertical(int distance)
    {     
       
        return movePic(0,distance);// 返回当前显示的图形

    }
    
    public ImageIcon movePic(int xdistance,int ydistance)
    {
    	System.out.println("xdistance,ydistance:"+xdistance+","+xdistance);
    	if (scale == 0)
    	{
    		// 不缩放
    		this.showCenterX+= xdistance;
            this.showCenterY += ydistance;            
        }
    	else if (scale > 0) 
    	{
    		// 放大
    		this.showCenterX += xdistance / scale;   
    		this.showCenterY += ydistance / scale;
        } 
    	else 
    	{
    		// 缩小
        	this.showCenterX += xdistance * -scale;
            this.showCenterY += ydistance * -scale;            
        }
        validateShowCenterY();
        validateShowCenterX();
        return this.cut();// 返回当前显示的图形
    }
    
    public void revert()
    {
        this.showCenterX = map.getWidth() / 2;// 设置图形视觉中心的水平坐标
        this.showCenterY = map.getHeight() / 2;// 设置图形视觉中心的垂直坐标
    }

    public void adjustShowCenter(int x, int y) 
    {
        this.showCenterX = x;
        this.showCenterY = y;
        validateShowCenterX();
        validateShowCenterY();
    }

    private void dealWithScale(int scale) 
    {
        if (scale == 0) 
        {
        	// 不缩放
            this.scale = 0;
        } 
        else
        {
            this.scale = scale / 100f;
            if (scale > 0)
            {
            	// 放大
            	this.scale += 1;
            } 
            else 
            {
            	// 缩小
                this.scale -= 1;
            }
        }
    }

    private void validateShowCenterX() 
    {
        int w = cutMapWidth / 2;
        if (cutMapWidth % 2 != 0)
        {
            w += 1;
        }
        if (showCenterX < w) 
        {
        	// 从图形左边缘开始截取
            showCenterX = w;
        } 
        else
        {
            if (showCenterX+w > map.getWidth()) 
            {
            	// 截取至图形右边缘
                showCenterX = map.getWidth() - w;
            }
        }
    }

    private void validateShowCenterY() 
    {
        int h = cutMapHeight / 2;
        if (cutMapHeight % 2 != 0)
        {
            h += 1;
        }
        if (showCenterY < h) 
        {
        	// 从图形上边缘开始截取
            showCenterY = h;
        } 
        else
        {
            if (showCenterY+h > map.getHeight()) 
            {
            	// 截取至图形下边缘
                showCenterY = map.getHeight() - h;
            }
        }
    }

    private void dealWithCutMapSize()
    {
        if (scale == 0) 
        {
        	// 不缩放
            cutMapWidth = viewportWidth;
            cutMapHeight = viewportHeight;
        } 
        else if (scale > 0) 
        {
        	// 放大(截取的图形区域变小)
            cutMapWidth = (int) (viewportWidth / scale);
            cutMapHeight = (int) (viewportHeight / scale);
        }
        else 
        {
        	// 缩小(截取的图形区域变大)
            cutMapWidth = Math.min((int) (viewportWidth * -scale), map.getWidth());
            cutMapHeight = Math.min((int) (viewportHeight * -scale),map.getHeight());            
        }
    }

    public BufferedImage getMap()
    {
        return map;
    }

    public void setShowCenterX(int showCenterX) 
    {
		this.showCenterX = showCenterX;
	}

	public void setShowCenterY(int showCenterY)
	{
		this.showCenterY = showCenterY;
	}

	public int getShowCenterX() 
	{
        return showCenterX;
    }

    public int getShowCenterY()
    {
        return showCenterY;
    }

    public int getCutMapWidth()
    {
        return cutMapWidth;
    }

    public int getCutMapHeight() 
    {
        return cutMapHeight;
    }

    public float getScale() 
    {
        return scale;
    }
}
